package com.sicong.gateway.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.*;

/**
 * 网关swagger资源配置类
 *
 * @author chenww
 * @date 2020-11-25
 */
@Primary
@Component
@Profile("dev")
public class Swagger2ResourceProvider implements SwaggerResourcesProvider {

    /**
     * swagger2默认的url后缀
     */
    private static final String SWAGGER2URL = "/v2/api-docs";

    /**
     * 网关路由
     */
    private final RouteLocator routeLocator;

    /**
     * 网关应用名称
     */
    @Value("${spring.application.name}")
    private String application;

    @Autowired
    public Swagger2ResourceProvider(RouteLocator routeLocator) {
        this.routeLocator = routeLocator;
    }

    @Override
    public List<SwaggerResource> get() {
        List<SwaggerResource> resources = new ArrayList<>();
        // 记录已经添加过的服务，存在同一个应用注册了多个服务在注册中心上
        Set<String> routeHosts = new HashSet<>();
        // 获取所有可用的host:serviceId
        routeLocator.getRoutes().filter(route -> route.getUri().getHost() != null)
                .filter(route -> !application.equals(route.getUri().getHost()))
                .subscribe(route -> routeHosts.add(route.getUri().getHost())).dispose();
        // 添加资源
        for (String instance : routeHosts) {
            resources.add(swaggerResource(instance));
        }
        return resources;
    }

    /**
     * 构造Swagger资源属性
     * @param instance 服务名
     * @return swagger资源
     */
    private SwaggerResource swaggerResource(String instance) {
        // 拼接url
        String url = "/" + instance.toLowerCase() + SWAGGER2URL;
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setUrl(url);
        swaggerResource.setName(instance);
        swaggerResource.setSwaggerVersion("2.0");
        return swaggerResource;
    }

}
